﻿#include "Hook.h"

#ifdef Q_OS_WIN
Hook::Hook()
{

}

static HHOOK keyHook = nullptr;
std::function<void(int,bool,bool)> Hook::m_func = nullptr;
bool m_bAuto = false;// 是否为自动按键，false代表是手动按下，true代表是自动按下。
int m_nKey = 0;// 上次的按键值
bool m_bDownOrUp = false;// 是否按下,false弹起,true按下。

LRESULT CALLBACK Hook::keyProc(int nCode,WPARAM wParam,LPARAM lParam)
{
    // GetAsyncKeyState 判断正在按下某键 取异步键状态 物理键状态（实际的）
    // GetKeyState GetKeyboardState 判断刚按过了某键 逻辑键状态（虚拟的）
    //    KBDLLHOOKSTRUCT *pkbhs=(KBDLLHOOKSTRUCT*)lParam;
    //    if(nCode == HC_ACTION){
    //            if(pkbhs->vkCode == VK_ESCAPE && GetAsyncKeyState(VK_CONTROL)& 0x8000 && GetAsyncKeyState(VK_SHIFT)&0x8000){
    //                        qDebug() << "Ctrl+Shift+Esc";
    //            }else if(pkbhs->vkCode == VK_ESCAPE && GetAsyncKeyState(VK_CONTROL) & 0x8000){
    //                qDebug() << "Ctrl+Esc";
    //            }else if(pkbhs->vkCode == VK_TAB && pkbhs->flags & LLKHF_ALTDOWN){
    //                qDebug() << "Alt+Tab";
    //            }else if(pkbhs->vkCode == VK_ESCAPE && pkbhs->flags &LLKHF_ALTDOWN){
    //                qDebug() << "Alt+Esc";
    //            }else if(pkbhs->vkCode == VK_LWIN || pkbhs->vkCode == VK_RWIN){
    //                qDebug() << "LWIN/RWIN";
    //            }else if(pkbhs->vkCode == VK_F4 && pkbhs->flags & LLKHF_ALTDOWN){
    //                qDebug() << "Alt+F4";
    //            }
    //            return CallNextHookEx(keyHook, nCode, wParam, lParam);//返回1表示截取消息不再传递,返回0表示不作处理,消息继续传递
    //        }

    // 当前进程
    HWND hwnd = GetForegroundWindow();
    DWORD Fid = GetWindowThreadProcessId(hwnd, NULL);
    DWORD Cid = GetCurrentThreadId();
    if (Fid != Cid)
    {
        return CallNextHookEx(keyHook, nCode, wParam, lParam);
    }

    KBDLLHOOKSTRUCT *pKBDLLHook= (KBDLLHOOKSTRUCT*)lParam;

    if(nCode == HC_ACTION){
        // 处理自动按下
        if (m_nKey == (int)pKBDLLHook->vkCode)
        {
            m_bAuto = true;
        }else
        {
            m_bAuto = false;
            m_nKey = pKBDLLHook->vkCode;
        }

        if (wParam== WM_KEYDOWN)
        {
            m_bDownOrUp = true;
        }
        if (wParam== WM_KEYUP)
        {
            m_bDownOrUp = false;
            m_bAuto = false;
            m_nKey = 0;
        }
    }

    if (m_func)
    {
        m_func(pKBDLLHook->vkCode, m_bDownOrUp, m_bAuto);
    }

    //     if (GetAsyncKeyState(VK_LSHIFT)&0x8000)
    //     {
    //         QDateTime dateTime;
    //         QString s;
    //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_LSHIFT";
    //         qDebug() << s;
    //     }
    //     if (GetAsyncKeyState(VK_RSHIFT)&0x8000)
    //     {
    //         QDateTime dateTime;
    //         QString s;
    //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_RSHIFT";
    //         qDebug() << s;
    //     }
    //     if (GetAsyncKeyState(VK_UP)&0x8000)
    //     {
    //         QDateTime dateTime;
    //         QString s;
    //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_UP";
    //         qDebug() << s;
    //     }
    //     if (GetAsyncKeyState(VK_DOWN)&0x8000)
    //     {
    //         QDateTime dateTime;
    //         QString s;
    //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_DOWN";
    //         qDebug() << s;
    //     }
    //     if (GetAsyncKeyState(VK_LEFT)&0x8000)
    //     {
    //         QDateTime dateTime;
    //         QString s;
    //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_LEFT";
    //         qDebug() << s;
    //     }
    //     if (GetAsyncKeyState(VK_RIGHT)&0x8000)
    //     {
    //         QDateTime dateTime;
    //         QString s;
    //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_RIGHT";
    //         qDebug() << s;
    //     }
    //     if (GetAsyncKeyState(VK_RETURN)&0x8000)
    //     {
    //         QDateTime dateTime;
    //         QString s;
    //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_RETURN";
    //         qDebug() << s;
    //     }
    //     if (GetAsyncKeyState(VK_ESCAPE )&0x8000)
    //     {
    //         QDateTime dateTime;
    //         QString s;
    //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_ESCAPE ";
    //         qDebug() << s;
    //     }

    //    if (wParam== WM_KEYUP && pKBDLLHook->vkCode== VK_F10)
    //    {
    //        QDateTime dateTime;
    //        QString s;
    //        s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_F10";
    //        qDebug() << s;
    //    }
    //    if (wParam== WM_KEYDOWN  && pKBDLLHook->vkCode== VK_F10)
    //    {
    //        QDateTime dateTime;
    //        QString s;
    //        s = "WM_KEYDOWN:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_F10";
    //        qDebug() << s;
    //    }
    //    if (wParam== WM_KEYUP && pKBDLLHook->vkCode== VK_TAB)
    //    {
    //        QDateTime dateTime;
    //        QString s;
    //        s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_TAB";
    //        qDebug() << s;
    //    }
    //    if (wParam== WM_KEYDOWN  && pKBDLLHook->vkCode== VK_TAB)
    //    {
    //        QDateTime dateTime;
    //        QString s;
    //        s = "WM_KEYDOWN:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_TAB";
    //        qDebug() << s;
    //    }
    //    if (wParam== WM_KEYUP && pKBDLLHook->vkCode== 'A')
    //    {
    //        QDateTime dateTime;
    //        QString s;
    //        s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - A";
    //        qDebug() << s;
    //    }
    //    if (wParam== WM_KEYDOWN  && pKBDLLHook->vkCode== 'A')
    //    {
    //        QDateTime dateTime;
    //        QString s;
    //        s = "WM_KEYDOWN:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - A";
    //        qDebug() << s;
    //    }
    //    if (pKBDLLHook->flags & LLKHF_ALTDOWN)
    //    {
    //        QDateTime dateTime;
    //        QString s;
    //        s = ":" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - LLKHF_ALTDOWN";
    //        qDebug() << s;
    //    }
    //    if (GetAsyncKeyState(VK_CONTROL)& 0x8000)
    //    {
    //        QDateTime dateTime;
    //        QString s;
    //        s = ":" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_CONTROL";
    //        qDebug() << s;
    //    }
    //    if (GetAsyncKeyState(VK_SHIFT)&0x8000)
    //    {
    //        QDateTime dateTime;
    //        QString s;
    //        s = ":" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_SHIFT";
    //        qDebug() << s;
    //    }
    //    if (GetKeyState(VK_CONTROL)&0x8000)
    //    {
    //        QDateTime dateTime;
    //        QString s;
    //        s = ":" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - GetKeyState VK_CONTROL";
    //        qDebug() << s;
    //    }
    //    if (GetKeyState(VK_SHIFT)&0x8000)
    //    {
    //        QDateTime dateTime;
    //        QString s;
    //        s = ":" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - GetKeyState VK_SHIFT";
    //        qDebug() << s;
    //    }
    //    if (wParam== WM_KEYUP && (pKBDLLHook->vkCode == VK_LWIN || pKBDLLHook->vkCode == VK_RWIN))
    //    {
    //        QDateTime dateTime;
    //        QString s;
    //        s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - WM_KEYUP WIN";
    //        qDebug() << s;
    //    }
    //    if (wParam== WM_KEYDOWN  && (pKBDLLHook->vkCode == VK_LWIN || pKBDLLHook->vkCode == VK_RWIN))
    //    {
    //        QDateTime dateTime;
    //        QString s;
    //        s = "WM_KEYDOWN:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - WM_KEYDOWN WIN";
    //        qDebug() << s;
    //    }
    return CallNextHookEx(keyHook, nCode, wParam, lParam);
}

void Hook::unInstallHook()
{
    if(keyHook != nullptr)// 原作者说是担心一次释放不稳定，才释放二次的。
    {
        UnhookWindowsHookEx(keyHook);//键盘钩子句不为空时销毁掉
        keyHook = nullptr;
    }
    if(keyHook != nullptr)
    {
        UnhookWindowsHookEx(keyHook);//键盘钩子句不为空时销毁掉
        keyHook = nullptr;
    }
}

void Hook::installHook()
{
    keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, keyProc, nullptr, 0);
}

#endif
